package org.netbeans.gpx.editor.view.track;

import org.netbeans.gpx.unit.LengthUnit;
import org.netbeans.gpx.unit.LengthUnitConverter;
import ca.odell.glazedlists.BasicEventList;
import ca.odell.glazedlists.EventList;
import ca.odell.glazedlists.swing.EventComboBoxModel;
import ca.odell.glazedlists.swing.EventTableModel;
import org.netbeans.gpx.model.api.Selection;
import org.netbeans.gpx.model.entity.Track;
import org.netbeans.gpx.model.entity.TrackSegment;
import org.netbeans.gpx.model.entity.Waypoint;
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.text.NumberFormat;
import java.util.List;
import javax.swing.DefaultListCellRenderer;
import javax.swing.JComponent;
import javax.swing.JList;
import org.netbeans.gpx.editor.GpxDataObject;
import org.netbeans.gpx.editor.binding.converter.BigIntegerConverter;
import org.netbeans.gpx.editor.panel.AbstractInnerPanel;
import org.netbeans.gpx.model.api.PositionCalculateable;
import org.netbeans.modules.xml.multiview.ui.SectionView;
import org.openide.util.Lookup;

/**
 *
 * @author msc
 */
public class TrackPanel extends AbstractInnerPanel implements PropertyChangeListener {

    private int trackNumber;

    private BigIntegerConverter bigIntegerConverter;

    private EventList<TrackSegment> segmentList;

    private PositionCalculateable positionCalculator;

    private LengthUnitAction lengthUnitAction;
    
    private NumberFormat numberFormat;

    public TrackPanel(SectionView sectionView, GpxDataObject gpxDataObject, int trackNumber) {
        super(sectionView, gpxDataObject);
        this.trackNumber = trackNumber;
        bigIntegerConverter = new BigIntegerConverter();
        segmentList = new BasicEventList<TrackSegment>();

        positionCalculator = Lookup.getDefault().lookup(PositionCalculateable.class);
        numberFormat = NumberFormat.getInstance();
        numberFormat.setMaximumFractionDigits(2);

        initComponents();

        lengthUnitAction = new LengthUnitAction();
        lengthUnitAction.addPropertyChangeListener(this);
        cmbDistanceUnit.setAction(lengthUnitAction);

        setValues();
    }

    private void setValues() {

        Track track = getCurrentTrack();
        txtNumber.setText(bigIntegerConverter.convertForward(track.getNumber()));
        txtName.setText(track.getName());
        txtCmt.setText(track.getCmt());
        txtSource.setText(track.getSrc());
        txtType.setText(track.getType());
        txtAreaDescr.setText(track.getDesc());
        setComboBoxModel(track.getTrackSegments());

    }

    private void setComboBoxModel(List<TrackSegment> segments) {

        EventComboBoxModel<TrackSegment> comboBoxModel = new EventComboBoxModel<TrackSegment>(segmentList);
        cmbSegments.setModel(comboBoxModel);
        if (!segments.isEmpty()) {
            segmentList.addAll(segments);
            TrackSegment firstSegment = segments.get(0);
            comboBoxModel.setSelectedItem(firstSegment);

            if (segments.size() > 1) {
                cmbSegments.setEnabled(true);
            }

            final List<Waypoint> trackpoints = firstSegment.getTrackpoints();
            setTableModel(trackpoints);
            setTotalDistance(trackpoints);
        }
    }

    private void setTableModel(List<Waypoint> trackPoints) {

        EventList<Waypoint> points = new BasicEventList<Waypoint>();
        points.addAll(trackPoints);
        EventTableModel<Waypoint> tableModel = new EventTableModel<Waypoint>(points, new WaypointTableFormat());
        tblPoints.setModel(tableModel);

        Selection.Instance.getContent().set(trackPoints, null);
    }

    private void setTotalDistance(final List<Waypoint> trackpoints) {
        double total = positionCalculator.getDistance(trackpoints);
        lengthUnitAction.setTotal(total);
        lengthUnitAction.actionPerformed(null);
    }

    /**
     * This method is called from within the constructor to initialize the form. WARNING: Do NOT modify this code. The
     * content of this method is always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        lblName = new javax.swing.JLabel();
        txtName = new javax.swing.JTextField();
        jScrollPane1 = new javax.swing.JScrollPane();
        tblPoints = new javax.swing.JTable();
        lblWayPoints = new javax.swing.JLabel();
        lblSegments = new javax.swing.JLabel();
        cmbSegments = new javax.swing.JComboBox();
        lblCmt = new javax.swing.JLabel();
        txtCmt = new javax.swing.JTextField();
        lblNumber = new javax.swing.JLabel();
        txtNumber = new javax.swing.JTextField();
        lblSource = new javax.swing.JLabel();
        txtSource = new javax.swing.JTextField();
        txtType = new javax.swing.JTextField();
        lblType = new javax.swing.JLabel();
        jScrollPane2 = new javax.swing.JScrollPane();
        txtAreaDescr = new javax.swing.JTextArea();
        lblDescr = new javax.swing.JLabel();
        lblTotal = new javax.swing.JLabel();
        lblTotalVal = new javax.swing.JLabel();
        cmbDistanceUnit = new javax.swing.JComboBox();

        lblName.setText(org.openide.util.NbBundle.getMessage(TrackPanel.class, "TrackPanel.lblName.text")); // NOI18N

        txtName.setText(org.openide.util.NbBundle.getMessage(TrackPanel.class, "TrackPanel.txtName.text")); // NOI18N

        tblPoints.setModel(new javax.swing.table.DefaultTableModel(
            new Object [][] {
                {null, null, null, null},
                {null, null, null, null},
                {null, null, null, null},
                {null, null, null, null}
            },
            new String [] {
                "Title 1", "Title 2", "Title 3", "Title 4"
            }
        ));
        jScrollPane1.setViewportView(tblPoints);

        lblWayPoints.setText(org.openide.util.NbBundle.getMessage(TrackPanel.class, "TrackPanel.lblWayPoints.text")); // NOI18N

        lblSegments.setText(org.openide.util.NbBundle.getMessage(TrackPanel.class, "TrackPanel.lblSegments.text")); // NOI18N

        cmbSegments.setEnabled(false);
        cmbSegments.setRenderer(new ComboBoxRenderer());

        lblCmt.setText(org.openide.util.NbBundle.getMessage(TrackPanel.class, "TrackPanel.lblCmt.text")); // NOI18N

        txtCmt.setText(org.openide.util.NbBundle.getMessage(TrackPanel.class, "TrackPanel.txtCmt.text")); // NOI18N

        lblNumber.setText(org.openide.util.NbBundle.getMessage(TrackPanel.class, "TrackPanel.lblNumber.text")); // NOI18N

        txtNumber.setText(org.openide.util.NbBundle.getMessage(TrackPanel.class, "TrackPanel.txtNumber.text")); // NOI18N

        lblSource.setText(org.openide.util.NbBundle.getMessage(TrackPanel.class, "TrackPanel.lblSource.text")); // NOI18N

        txtSource.setText(org.openide.util.NbBundle.getMessage(TrackPanel.class, "TrackPanel.txtSource.text")); // NOI18N

        txtType.setText(org.openide.util.NbBundle.getMessage(TrackPanel.class, "TrackPanel.txtType.text")); // NOI18N

        lblType.setText(org.openide.util.NbBundle.getMessage(TrackPanel.class, "TrackPanel.lblType.text")); // NOI18N

        txtAreaDescr.setColumns(20);
        txtAreaDescr.setRows(4);
        jScrollPane2.setViewportView(txtAreaDescr);

        lblDescr.setText(org.openide.util.NbBundle.getMessage(TrackPanel.class, "TrackPanel.lblDescr.text")); // NOI18N

        lblTotal.setText(org.openide.util.NbBundle.getMessage(TrackPanel.class, "TrackPanel.lblTotal.text")); // NOI18N

        lblTotalVal.setText(org.openide.util.NbBundle.getMessage(TrackPanel.class, "TrackPanel.lblTotalVal.text")); // NOI18N

        cmbDistanceUnit.setModel(new javax.swing.DefaultComboBoxModel(LengthUnit.values()));

        org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(this);
        this.setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(layout.createSequentialGroup()
                .addContainerGap()
                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                    .add(layout.createSequentialGroup()
                        .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                            .add(lblCmt)
                            .add(lblSource)
                            .add(lblType)
                            .add(lblDescr)
                            .add(lblName)
                            .add(lblNumber))
                        .add(14, 14, 14)
                        .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                            .add(layout.createSequentialGroup()
                                .add(txtNumber, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 86, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                                .addContainerGap())
                            .add(layout.createSequentialGroup()
                                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                                    .add(txtName, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 664, Short.MAX_VALUE)
                                    .add(txtSource, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 664, Short.MAX_VALUE)
                                    .add(txtCmt, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 664, Short.MAX_VALUE)
                                    .add(txtType, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 664, Short.MAX_VALUE)
                                    .add(jScrollPane2, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 664, Short.MAX_VALUE))
                                .add(43, 43, 43))))
                    .add(layout.createSequentialGroup()
                        .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                            .add(jScrollPane1, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 781, Short.MAX_VALUE)
                            .add(layout.createSequentialGroup()
                                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                                    .add(lblWayPoints)
                                    .add(layout.createSequentialGroup()
                                        .add(lblSegments)
                                        .add(18, 18, 18)
                                        .add(cmbSegments, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                                        .add(35, 35, 35)
                                        .add(lblTotal)
                                        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                                        .add(cmbDistanceUnit, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                                        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                                        .add(lblTotalVal, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 165, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)))
                                .add(0, 0, Short.MAX_VALUE)))
                        .addContainerGap())))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(layout.createSequentialGroup()
                .addContainerGap()
                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                    .add(lblNumber)
                    .add(txtNumber, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                    .add(txtName, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                    .add(lblName))
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                    .add(lblCmt)
                    .add(txtCmt, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                    .add(txtSource, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                    .add(lblSource))
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                    .add(txtType, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                    .add(lblType))
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                    .add(lblDescr)
                    .add(jScrollPane2, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
                .add(12, 12, 12)
                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                    .add(lblTotalVal, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 20, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                    .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                        .add(lblSegments)
                        .add(cmbSegments, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                        .add(lblTotal)
                        .add(cmbDistanceUnit, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)))
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(lblWayPoints)
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(jScrollPane1, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 330, Short.MAX_VALUE)
                .addContainerGap())
        );
    }// </editor-fold>//GEN-END:initComponents
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JComboBox cmbDistanceUnit;
    private javax.swing.JComboBox cmbSegments;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JScrollPane jScrollPane2;
    private javax.swing.JLabel lblCmt;
    private javax.swing.JLabel lblDescr;
    private javax.swing.JLabel lblName;
    private javax.swing.JLabel lblNumber;
    private javax.swing.JLabel lblSegments;
    private javax.swing.JLabel lblSource;
    private javax.swing.JLabel lblTotal;
    private javax.swing.JLabel lblTotalVal;
    private javax.swing.JLabel lblType;
    private javax.swing.JLabel lblWayPoints;
    private javax.swing.JTable tblPoints;
    private javax.swing.JTextArea txtAreaDescr;
    private javax.swing.JTextField txtCmt;
    private javax.swing.JTextField txtName;
    private javax.swing.JTextField txtNumber;
    private javax.swing.JTextField txtSource;
    private javax.swing.JTextField txtType;
    // End of variables declaration//GEN-END:variables

    List<Track> getTracks() {
        return getGpx().getTracks();
    }

    Track getCurrentTrack() {
        return getGpx().getTracks().get(trackNumber);
    }

    @Override
    public void setValue(JComponent source, Object value) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public void linkButtonPressed(Object ddBean, String ddProperty) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public JComponent getErrorComponent(String errorId) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public void propertyChange(PropertyChangeEvent evt) {
        if (evt.getPropertyName().equals(LengthUnitAction.UNIT)) {
            double dist = (Double)evt.getNewValue();
            lblTotalVal.setText(numberFormat.format(dist));
        }
    }

    private class ComboBoxRenderer extends DefaultListCellRenderer {

        @Override
        public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected,
            boolean cellHasFocus) {

            String text = Integer.toString(segmentList.indexOf(value) + 1);
            return super.getListCellRendererComponent(list, text, index, isSelected, cellHasFocus);
        }
    }
}
